package net.esj.basic.core.engine.support.message;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import net.esj.basic.core.engine.factory.bean.BeanFactoryContextUtils;
import net.esj.basic.utils.StringUtils;

public class MessageProvidersFactory implements MessageProvider{

	private List<MessageProvider> providers  = new ArrayList<MessageProvider>(0);
	
	private static MessageProvidersFactory _instance;
	
	@Override
	public String getMessage(String sourceName, String code, Object[] args,
			String defaultMessage, Locale locale) {
		String retal = null;
		for(MessageProvider provider : providers){
			retal = provider.getMessage(sourceName, code, args, defaultMessage, locale);
			if(org.apache.commons.lang.StringUtils.equals(retal, code)){
				continue;
			}
			if(StringUtils.hasText(retal)){
				break;
			}
		}
		return retal;
	}

	@Override
	public String getMessage(String sourceName, String code, Object[] args,
			Locale locale) throws NoSuchMessageException {
		String retal = null;
		for(MessageProvider provider : providers){
			retal = provider.getMessage(sourceName, code, args, locale);
			if(org.apache.commons.lang.StringUtils.equals(retal, code)){
				continue;
			}
			if(StringUtils.hasText(retal)){
				break;
			}
		}
		return retal;
	}

	@Override
	public String getMessage(String sourceName, MessageResolver resolver,
			Locale locale) throws NoSuchMessageException {
		String retal = null;
		for(MessageProvider provider : providers){
			retal = provider.getMessage(sourceName, resolver, locale);
			if(StringUtils.hasText(retal)){
				break;
			}
		}
		return retal;
	}

	private void listProviders(){
		Map<String, MessageProvider> map = BeanFactoryContextUtils.getBeansByType(MessageProvider.class);
		providers.addAll(map.values());
		Collections.sort(providers,new Comparator<MessageProvider>() {

			@Override
			public int compare(MessageProvider o1, MessageProvider o2) {
				return o1.order()-o2.order();
			}
		});
	}
	
	public void regisitry(MessageProvider provider){
		providers.add(provider);
	}
	
	public static MessageProvidersFactory getInstance(){
		if(_instance==null){
			_instance = new MessageProvidersFactory();
			_instance.listProviders();
		}
		return _instance;
	}

	@Override
	public int order() {
		return 0;
	}
}
